Telegram Group & Telegram Channel
🐹 Задача для Go 1.21+: «Контекст отменён, но горутина продолжает работу»

📌 Актуально для: Go 1.21 и новее (введён `context.WithCancelCause`)
🎯 Цель: Понять, почему горутина не завершилась по отменённому контексту

📍 Ситуация:

Ты используешь контекст для управления жизненным циклом горутины. В Go 1.21 ты решил использовать context.WithCancelCause:


package main

import (
"context"
"fmt"
"time"
)

func main() {
ctx, cancel := context.WithCancelCause(context.Background())
go worker(ctx)

time.Sleep(1 * time.Second)
cancel(fmt.Errorf("manual stop"))

time.Sleep(2 * time.Second)
}

func worker(ctx context.Context) {
<-ctx.Done()
fmt.Println("Worker stopped:", context.Cause(ctx))
}


🔍 Ты ожидаешь, что горутина завершится и выведет:


Worker stopped: manual stop


Но вместо этого — программа завершилась без вывода. Почему?

🧩 Вопросы:

1. Почему worker не печатает "Worker stopped: ..."?
2. Что изменилось в context.WithCancelCause по сравнению с WithCancel?
3. Как безопасно читать причину отмены?
4. Как изменить worker, чтобы он корректно завершался?
5. Почему важно не блокироваться на `ctx.Done()`, если возможна гонка?

🛠 Решение:

🔸 В Go 1.21 есть `context.WithCancelCause`, который позволяет задавать причину отмены.
Но `context.Cause(ctx)` вернёт `nil`, **если ты используешь `context.WithCancel`**, либо, если `ctx.Done()` не был срабатывающим.

🔸 В этом коде `worker(ctx)` запускается и сразу блокируется на:

<-ctx.Done()


Но если отмена происходит **до** того, как `worker` успел начать слушать `ctx.Done()`, и ты используешь старую `WithCancel`, `context.Cause` вернёт `nil`.

🔸 **Правильный способ:**

Убедись, что `context.WithCancelCause` действительно используется и `ctx.Done()` слушается вовремя.

Для Go 1.21+ пример рабочий:



func worker(ctx context.Context) {
for {
select {
case <-ctx.Done():
fmt.Println("Worker stopped:", context.Cause(ctx))
return
case <-time.After(100 * time.Millisecond):
fmt.Println("Working...")
}
}
}



🔸 Альтернатива для старых версий Go (<1.21):


ctx, cancel := context.WithCancel(context.Background())
...
fmt.Println("Worker stopped:", ctx.Err()) // вместо Cause


📌 Вывод:
Начиная с Go 1.21, `context.WithCancelCause` даёт более точный контроль за причинами отмены. Но горутины всё равно должны явно проверять `ctx.Done()` через `select`, иначе отмена может пройти незаметно.



tg-me.com/golangtests/790
Create:
Last Update:

🐹 Задача для Go 1.21+: «Контекст отменён, но горутина продолжает работу»

📌 Актуально для: Go 1.21 и новее (введён `context.WithCancelCause`)
🎯 Цель: Понять, почему горутина не завершилась по отменённому контексту

📍 Ситуация:

Ты используешь контекст для управления жизненным циклом горутины. В Go 1.21 ты решил использовать context.WithCancelCause:


package main

import (
"context"
"fmt"
"time"
)

func main() {
ctx, cancel := context.WithCancelCause(context.Background())
go worker(ctx)

time.Sleep(1 * time.Second)
cancel(fmt.Errorf("manual stop"))

time.Sleep(2 * time.Second)
}

func worker(ctx context.Context) {
<-ctx.Done()
fmt.Println("Worker stopped:", context.Cause(ctx))
}


🔍 Ты ожидаешь, что горутина завершится и выведет:


Worker stopped: manual stop


Но вместо этого — программа завершилась без вывода. Почему?

🧩 Вопросы:

1. Почему worker не печатает "Worker stopped: ..."?
2. Что изменилось в context.WithCancelCause по сравнению с WithCancel?
3. Как безопасно читать причину отмены?
4. Как изменить worker, чтобы он корректно завершался?
5. Почему важно не блокироваться на `ctx.Done()`, если возможна гонка?

🛠 Решение:

🔸 В Go 1.21 есть `context.WithCancelCause`, который позволяет задавать причину отмены.
Но `context.Cause(ctx)` вернёт `nil`, **если ты используешь `context.WithCancel`**, либо, если `ctx.Done()` не был срабатывающим.

🔸 В этом коде `worker(ctx)` запускается и сразу блокируется на:

<-ctx.Done()


Но если отмена происходит **до** того, как `worker` успел начать слушать `ctx.Done()`, и ты используешь старую `WithCancel`, `context.Cause` вернёт `nil`.

🔸 **Правильный способ:**

Убедись, что `context.WithCancelCause` действительно используется и `ctx.Done()` слушается вовремя.

Для Go 1.21+ пример рабочий:



func worker(ctx context.Context) {
for {
select {
case <-ctx.Done():
fmt.Println("Worker stopped:", context.Cause(ctx))
return
case <-time.After(100 * time.Millisecond):
fmt.Println("Working...")
}
}
}



🔸 Альтернатива для старых версий Go (<1.21):


ctx, cancel := context.WithCancel(context.Background())
...
fmt.Println("Worker stopped:", ctx.Err()) // вместо Cause


📌 Вывод:
Начиная с Go 1.21, `context.WithCancelCause` даёт более точный контроль за причинами отмены. Но горутины всё равно должны явно проверять `ctx.Done()` через `select`, иначе отмена может пройти незаметно.

BY Go tests


Warning: Undefined variable $i in /var/www/tg-me/post.php on line 283

Share with your friend now:
tg-me.com/golangtests/790

View MORE
Open in Telegram


Go tests Telegram | DID YOU KNOW?

Date: |

Traders also expressed uncertainty about the situation with China Evergrande, as the indebted property company has not provided clarification about a key interest payment.In economic news, the Commerce Department reported an unexpected increase in U.S. new home sales in August.Crude oil prices climbed Friday and front-month WTI oil futures contracts saw gains for a fifth straight week amid tighter supplies. West Texas Intermediate Crude oil futures for November rose $0.68 or 0.9 percent at 73.98 a barrel. WTI Crude futures gained 2.8 percent for the week.

Find Channels On Telegram?

Telegram is an aspiring new messaging app that’s taking the world by storm. The app is free, fast, and claims to be one of the safest messengers around. It allows people to connect easily, without any boundaries.You can use channels on Telegram, which are similar to Facebook pages. If you’re wondering how to find channels on Telegram, you’re in the right place. Keep reading and you’ll find out how. Also, you’ll learn more about channels, creating channels yourself, and the difference between private and public Telegram channels.

Go tests from tw


Telegram Go tests
FROM USA